package hr.fer.zpr.nmbp.project2.dao;

import hr.fer.zpr.nmbp.project2.dao.exceptions.DAOException;
import hr.fer.zpr.nmbp.project2.dao.util.CPLoader;
import java.net.URL;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import org.h2.jdbcx.JdbcConnectionPool;
import org.h2.tools.Server;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;


public class DAOFactory {

	private static final String DB_PROPERTIES = "hr/fer/zpr/nmbp/project2/dao/res/h2.properties";
	private static final String DB_TABLES = "hr/fer/zpr/nmbp/project2/dao/res/tables.sql";
    private static final String HIB_PROPERTIES = "hr/fer/zpr/nmbp/project2/dao/res/hibernate.cfg.xml";
    
    private static Server server = null;
    private static SessionFactory sessionFactory = null;
    private static Session session = null;

    
	public static void init() {
		try {
			Class.forName("org.h2.Driver");
			server = Server.createTcpServer().start();
            initTables();
            
            URL url = DAOFactory.class.getClassLoader().getResource(HIB_PROPERTIES);
            sessionFactory = new AnnotationConfiguration().configure(url).buildSessionFactory();
            session = sessionFactory.openSession();
		} catch (Exception e) {
			throw new DAOException(e.getMessage());
		}	
	}
    
    /**
	 * Pomoćna metoda koja stvori bazu podataka,
     * i tablice ako baza ne postoji.
	 * Parsiraju se iz datoteke DB_TABLES.
	 * @param conn
	 */
	private static void initTables() throws SQLException {
		JdbcConnectionPool connPool = null;
        Connection conn = null;
        try {
            Properties dbProp = CPLoader.loadProperties(DB_PROPERTIES);
			connPool = JdbcConnectionPool.create(dbProp.getProperty("URL"),
							dbProp.getProperty("username"), dbProp.getProperty("password"));
                    
			conn = connPool.getConnection();
			Statement st = conn.createStatement();
			st.execute(CPLoader.loadString(DB_TABLES));
		} finally {
			try { conn.close(); } catch (Exception ignorable) {}
            try { connPool.dispose(); } catch (Exception ignorable) {}
		}		
	}

	public static void close(){
		try {
			if (server != null) {
                sessionFactory.close();
                server.stop();
                server.shutdown();
				server = null;
			}
		} catch (Exception e) {
			throw new DAOException(e.getMessage());
		}
	}
    
	public static BolestDAO getBolestDAO() {
		return new BolestDAO(session);
	}	

	public static BolnicaDAO getBolnicaDAO() {
		return new BolnicaDAO(session);
	}	

	public static DijagnozaDAO getDijagnozaDAO() {
		return new DijagnozaDAO(session);
	}	

	public static KartonDAO getKartonDAO()	{
		return new KartonDAO(session);
	}	

	public static LijecnikDAO getLijecnikDAO()	{
		return new LijecnikDAO(session);
	}	

	public static PacijentDAO getPacijentDAO()	{
		return new PacijentDAO(session);
	}
}
